package com.yfbao.horizon.sudoku;

import com.yfbao.horizon.utils.IDUtil;
import lombok.Data;

import java.io.Serializable;
import java.util.*;

@Data
public class MatrixDto implements Serializable {
    private List<List<IndexValueDto>> listValue = new ArrayList<>();

    private Set<Integer> valueSet = new HashSet<>();
    private Integer order;
    private String key;
    private MatrixDto currentMatrixDto;

    private List<MatrixDto> sourMatrixList=null;

    public MatrixDto(int order,String key){
        this.order=order;
        this.key =key;
//        this.key = IDUtil.getUUID();
    }

    public void initData(int row,int column,int value){
        if(listValue.isEmpty()){
            initList();
        }
        if(valueSet.contains(value)){
            throw new RuntimeException("该值已存在");
        }
        listValue.get(row).get(column).initData(value);
        valueSet.add(value);
    }

    public void clear(){
        currentMatrixDto=null;
    }

    public boolean containValue(int value){
        for(int i=0;i<order;i++){
            for(int j=0;j<order;j++){
                Integer integer = listValue.get(i).get(j).getCurrentValue();
                if(value == integer){
                    return true;
                }
            }
        }
        return false;
    }

    public void setValue(int row,int column,int value){
        if(listValue.isEmpty()){
            initList();
        }
        boolean invalid = listValue.get(row).get(column).isInvalid(value);
        if(invalid || value==0){
            throw new RuntimeException("不合理的值:"+value);
        }
        if(valueSet.contains(value) && value!=0){
            throw new RuntimeException("该值已存在");
        }
        listValue.get(row).get(column).setCurrentValue(value);
        valueSet.add(value);
    }

    public boolean isFinished(){
        if(valueSet.size()==(order*order)){
            return true;
        }
        return false;
    }

    public void setCurrentMatrixDto(Integer listNum){
        if(sourMatrixList==null || listNum>=sourMatrixList.size()){
            throw new RuntimeException("请先计算备选列表或下标位不合法");
        }
        this.currentMatrixDto = sourMatrixList.get(listNum);
    }

    public List<Integer> getAvailableValue(){
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=1;i<=(order*order);i++){
            if(valueSet.contains(i)){
                continue;
            }
            list.add(i);
        }
        return list;
    }

    public IndexValueDto getValue(int row,int column){
        if(currentMatrixDto !=null){
            return currentMatrixDto.getValue(row,column);
        }
        if(listValue.isEmpty()){
            initList();
        }
        IndexValueDto integer = listValue.get(row).get(column);
        return integer;
    }

    public Integer getMatrixOrder(){
        return this.order;
    }


    private void initList(){
        for(int i=0;i<this.order;i++){
            List<IndexValueDto> columnList = new ArrayList<>();
            for(int j=0;j<this.order;j++){
                columnList.add(j,new IndexValueDto());
            }
            listValue.add(i,columnList);
        }
    }
}
